package com.nulldev.util.java.swing.canvas;

import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Designed for use with AWT NOT Swing.<br>
 * <b>WARNING:</b> This will not work with {@link com.nulldev.util.java.swing.extSwing.legacy.ePanel}
 * @author null
 *
 */
public abstract class DynamicCanvas extends Canvas{

	protected static long FRAME_RATE = (1000L / 40L);
	protected static long BUFFERS = 4;

	private ExecutorService pool;
	private BufferStrategy strat;
	public DynamicCanvas() {
		super();
		this.pool = Executors.newCachedThreadPool();//newWorkStealingPool();
	}

	@Override
    public void addNotify() {
        super.addNotify();
        this.createBufferStrategy((int) this.BUFFERS);
        this.strat = this.getBufferStrategy();
    }

	@Override
	public void paint(final Graphics g) {
		super.paint(g);
        if (this.strat == null) {
            this.createBufferStrategy((int) this.BUFFERS);
            this.strat = this.getBufferStrategy();
        }
        this.drawHandle((Graphics2D) g);
	}

	private void drawHandle(final Graphics2D g2d) {
		pool.execute(new Runnable() {

			@Override
			public void run() {
				Graphics2D g2d = null;//(Graphics2D) (DynamicCanvas.this.strat.getDrawGraphics() == null ? DynamicCanvas.this.getGraphics() : DynamicCanvas.this.strat.getDrawGraphics());
				try {
					if (DynamicCanvas.this.strat.getDrawGraphics() != null) {
						g2d = (Graphics2D) DynamicCanvas.this.strat.getDrawGraphics();
					}
				}catch (Exception e) {
					g2d = (Graphics2D) DynamicCanvas.this.getGraphics();
				}
				DynamicCanvas.this.drawCanvas(g2d);
				try {
					DynamicCanvas.this.strat.show();
					//Toolkit.getDefaultToolkit().sync();
				}catch (Exception e) {
					DynamicCanvas.this.drawCanvas((Graphics2D) DynamicCanvas.this.getGraphics());
				}
				try {
					Thread.sleep(FRAME_RATE);
					DynamicCanvas.this.paintAll(g2d);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public abstract void drawCanvas(final Graphics2D g2d);
}
